package com.jinhongone.pattern.creater.singleton.demo4;

/*
* 单例模式-懒汉模式-双重检查锁方式【推荐】
* 该模式是在【懒汉模式-线程安全模式】上优化得来，懒汉模式-线程安全是通过加锁解决的线程问题，但获取对象单例操作时绝大多数都是读操作（只是读取，没有赋值操作就是读操作）
* 加锁会导致性能较差，在此情况下优化出双重检查锁模式
* */
public class Singleton {

    private Singleton(){}
//   此处使用volatile关键词，实时同步该静态对象，确保其可见性
    private static volatile Singleton singleton;

    public static Singleton getInstance(){
//      第一次检测：可能会出现线程安全问题
        if(singleton == null){
//      第二次检测：为了防止线程安全问题，加锁，由于静态方法中没有this，锁字节码文件,由于是第二次检测时加锁，性能消耗减低。
//                为了防止java代码指令优化和重排，在静态变量处使用volatile关键字确保变量多线程实时最近。
            synchronized (Singleton.class){
                //此次再次检测是为了防止多线程同时过了第一重检测，在等待锁场景，不添加第二次检测会导致直接new对象，产生多个对象，所以要添加第二次检测，防止后续线程创建新对象。
                if(singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
